import Logger from './Logger'

export default class urlUtil {
  static _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

  static stringToUint8Array(str: string) {
    let arr = new Uint8Array(str.length);
    for (let i = 0, j = str.length; i < j; ++i) {
      arr[i] = str.charCodeAt(i);
    }
    return arr;
  }

  static encode(input) {
    let output = [];
    let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
    let i = 0, len = input.length, remainingBytes = len;
    let isArray = typeof (input) !== "string";
    while (i < input.length) {
      remainingBytes = len - i;
      if (!isArray) {
        chr1 = input.charCodeAt(i++);
        chr2 = i < len ? input.charCodeAt(i++) : 0;
        chr3 = i < len ? input.charCodeAt(i++) : 0;
      } else {
        chr1 = input[i++];
        chr2 = i < len ? input[i++] : 0;
        chr3 = i < len ? input[i++] : 0;
      }
      enc1 = chr1 >> 2;
      enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
      enc3 = remainingBytes > 1 ? (((chr2 & 15) << 2) | (chr3 >> 6)) : 64;
      enc4 = remainingBytes > 2 ? (chr3 & 63) : 64;
      output.push(urlUtil._keyStr.charAt(enc1) + urlUtil._keyStr.charAt(enc2) + urlUtil._keyStr.charAt(enc3) +
      urlUtil._keyStr.charAt(enc4));
    }
    return output.join("");
  };

  static btoa(s) {
    let i;
    s = String(s);
    for (i = 0; i < s.length; i++) {
      if (s.charCodeAt(i) > 255) {
        return null;
      }
    }
    let out = '';
    for (i = 0; i < s.length; i += 3) {
      let groupsOfSix = [undefined, undefined, undefined, undefined];
      groupsOfSix[0] = s.charCodeAt(i) >> 2;
      groupsOfSix[1] = (s.charCodeAt(i) & 0x03) << 4;
      if (s.length > i + 1) {
        groupsOfSix[1] |= s.charCodeAt(i + 1) >> 4;
        groupsOfSix[2] = (s.charCodeAt(i + 1) & 0x0f) << 2;
      }
      if (s.length > i + 2) {
        groupsOfSix[2] |= s.charCodeAt(i + 2) >> 6;
        groupsOfSix[3] = s.charCodeAt(i + 2) & 0x3f;
      }
      for (let j = 0; j < groupsOfSix.length; j++) {
        if (typeof groupsOfSix[j] == 'undefined') {
          out += '=';
        } else {
          out += urlUtil.btoaLookup(groupsOfSix[j]);
        }
      }
    }
    return out;
  }

  static btoaLookup(idx) {
    if (idx < 26) {
      return String.fromCharCode(idx + 'A'.charCodeAt(0));
    }
    if (idx < 52) {
      return String.fromCharCode(idx - 26 + 'a'.charCodeAt(0));
    }
    if (idx < 62) {
      return String.fromCharCode(idx - 52 + '0'.charCodeAt(0));
    }
    if (idx == 62) {
      return '+';
    }
    if (idx == 63) {
      return '/';
    }
  }

  static toBase64(buffer) {
    let TAG = "_:_toBase64"
    let binary = ''
    console.log(TAG, "entered",typeof buffer)
    let bytes
    try {
      bytes = new Uint8Array(buffer)
    } catch (e) {
      console.log(TAG, JSON.stringify(e))
      return ""
    }
    console.log("bytes--" + bytes)
    let len = bytes.length
    for (let i = 0; i < len; i++) {
      binary += String.fromCharCode(bytes[i])
    }
    return urlUtil.btoa(binary)
  }

  static StrToBase64(str) {
    return urlUtil.toBase64(urlUtil.stringToUint8Array(str))
  }
}